# 变量

# 1.变量的使用
# 先定义 后引用
a = 100  # 定义
print(a)  # 引用

# 2.内存管理: 垃圾回收机制
# 垃圾：当内存中一个变量值绑定的变量名数量为0时，称为垃圾
# 引用计数增加
x = 10  # 10的引用计数为1
y = x  # 10的引用计数为2
z = x  # 10的引用计数为3

# 引用计数减少
del x  # 变量名x与10解除绑定关系，10的引用计数由3减少1变为2
# print(x)  # 报错 ” NameError: name 'x' is not defined “ 变量名 x 未定义
del y  # 变量名y与10解除绑定关系，10的引用计数由2减少1变为1
z = 20  # z的引用指向20，此时z与10解除了绑定关系，10的引用计数为0，变为垃圾被系统回收
print(z)

# 循环引用
l1 = [10]
l2 = [20]
l1.append(l2)  # l1 = [10的内存地址,l2的内存地址]
l2.append(l1)  # l2 = [20的内存地址,l1的内存地址]
# 此时l1和l2发生了循环引用，会引发内存溢出
print(l1)
print(l2)
del l1
del l2
# l1和l2的直接引用已经解除，但是依然被间接引用，python解释器会标记清除，过段时间，会自动释放没有直接引用的内存

# 3.id和type
# id：显示变量的内存地址，内存地址不同则id不同
# type：显示变量的类型
name = 'tom'
print(name)
print(id(name))
print(type(name))

# 4.基本数据类型

# int 不可变类型
age = 18
print(type(age))

# float 不可变类型
salary = 1.3
print(type(salary))

# str 不可变类型
name = 'tom'
print(type(name))

# 列表 可变类型
l = [10, 3.2, 'aaa', ['bbb', 'ccc']]
print(l[0])  # 输出 10
print(l[3][1]) # 输出 ccc
# 列表中存的是内存地址
a = 10
l1 = [5,a]  # 列表中存的是10的内存地址，所以当a的引用发生变化时，l1[1]依然是10
print(l1[1])  # 输出 10
a = 20
print(l1[1])  # 输出 10

# 字典 可变类型
d = {'a':1,'b':2}
print(d['a'])  # 输出 1
# 布尔值 不可变类型
is_true = True
is_false = False
print(type(is_true))
print(is_true == is_true)  # 输出 true
print(is_true == is_false)  # 输出 false
